package com.example.demo.sf;

import java.util.Iterator;
import java.util.Optional;
import java.util.function.Consumer;

/**
 * 双向链表(带哨兵)
 */
public  class DoublySignalLinkedList implements Iterable<Integer>{

    private Node head; //头节点
    private Node tail; //尾节点

    public DoublySignalLinkedList() {
        //创建一个头节点
        head = new Node();
        //创建一个尾节点
        tail = new Node();
        //头节点和尾节点之间建立关系
        head.next = tail;
        tail.pre = head;
    }



    /**
     * 这里静态内部类主要是为了对外隐藏节点类
     * 复习一个知识点
     * 为什么要用static 关键字   什么时候内部类加载static 什么时候不用
     * 当内部类不依赖外部类的成员变量的时候，内部类可以加static关键字
     *
     */
    private static class Node {
        private Node pre; // 上一个节点指针
        private int value; // 值
        private Node next; // 下一个节点指针

        public Node() {
        }

        public Node(Node pre,int value, Node next) {
            this.pre = pre;
            this.value = value;
            this.next = next;
        }
    }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            Node cur = head.next;
            @Override
            public boolean hasNext() {
                return cur != tail;
            }

            @Override
            public Integer next() {
                int value = cur.value;
                cur = cur.next;
                return value;
            }
        };
    }



    /**
     * 根据索引查找元素
     */
    public Node getNode(int index) {
        int i= 0;
        for (Node cur = head.next; cur != tail; cur = cur.next){
            if (i == index){
                return cur;
            }
        }
        return null;
    }
    /**
     * 删除最后一个节点
     */
    public void removeLast() {
        // 获取到最后一个节点
        Node last = tail.pre;
        if (last == head) {
            System.out.println("数组越界");
            return;
        }
        // 获取最后一个节点的上一个节点
        Node pre = last.pre;
        pre.next = tail;
        tail.pre = pre;
    }

    /**
     * 在末尾插入一个元素
     */
    public void addLast(int value) {
        Node node = new Node(tail.pre, value, tail);
        tail.pre = node;
        node.pre.next = node;
    }


    /**
     * 根据索引删除元素
     */
    public void remove(int index) {
        //首先找打待删除节点的上一个节点
        Node pre = getNode(index -1);
        if (pre == null) {
            System.out.println("数组越界");
            return;
        }
        // 在找到待删除节点
        Node cur = pre.next;
        if (cur == tail) {
            System.out.println("数组越界");
            return;
        }
        // 找到待删除节点的下一个节点
        Node next = cur.next;
        pre.next = next;
        next.pre = pre;

    }

    /**
     * 按照索引位置插入元素
     */
    public void add(int index, int value) {
        // 获取上一个节点
        Node pre = getNode(index -1);
        if (pre == null) {
            System.out.println("数组越界");
            return;
        }
        // 获取下一个节点
        Node next = pre.next;
        //创建要插入的节点
        Node node = new Node(pre, value, next);
        //上一个节点的next 指向插入的节点
        pre.next = node;
        //下一个节点的pre 节点指向插入的节点
        next.pre = node;
    }

}
